package cn.luoxiaolong.android.picker.file

import android.Manifest
import android.annotation.SuppressLint
import android.app.Activity
import android.content.Intent
import android.content.pm.PackageManager
import android.graphics.Color
import android.os.Bundle
import android.os.Environment
import android.os.Environment.MEDIA_MOUNTED
import android.support.v4.app.ActivityCompat
import android.support.v4.content.ContextCompat
import android.support.v4.widget.SwipeRefreshLayout
import android.support.v7.widget.LinearLayoutManager
import android.support.v7.widget.OrientationHelper
import android.support.v7.widget.RecyclerView
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.animation.AnimationUtils
import android.widget.*
import cn.luoxiaolong.android.picker.file.R.string
import cn.luoxiaolong.android.picker.file.adapter.BaseAdapter
import cn.luoxiaolong.android.picker.file.adapter.FileListAdapter
import cn.luoxiaolong.android.picker.file.adapter.FileNavAdapter
import cn.luoxiaolong.android.picker.file.adapter.RecyclerViewListener
import cn.luoxiaolong.android.picker.file.bean.BeanSubscriber
import cn.luoxiaolong.android.picker.file.bean.FileBean
import cn.luoxiaolong.android.picker.file.bean.FileItemBeanImpl
import cn.luoxiaolong.android.picker.file.bean.FileNavBeanImpl
import cn.luoxiaolong.android.picker.file.config.FilePickerManager
import cn.luoxiaolong.android.picker.file.utils.BaseActivity
import cn.luoxiaolong.android.picker.file.utils.FileUtils
import cn.luoxiaolong.android.picker.file.widget.BaseItemDecoration
import cn.luoxiaolong.android.picker.file.widget.LinerItemDecoration
import cn.luoxiaolong.android.picker.file.widget.PosLinearLayoutManager
import cn.luoxiaolong.android.picker.file.widget.RecyclerViewFilePicker
import kotlinx.coroutines.launch
import java.io.File
import java.util.concurrent.atomic.AtomicInteger

@SuppressLint("ShowToast")
class FilePickerActivity : BaseActivity(), View.OnClickListener,
    RecyclerViewListener.OnItemClickListener,
    BeanSubscriber {
    private var swipeRefreshLayout: SwipeRefreshLayout? = null
    /**
     * 文件列表适配器
     */
    private var listAdapter: FileListAdapter? = null
    /**
     * 导航栏列表适配器
     */
    private var navAdapter: FileNavAdapter? = null
    /**
     * 导航栏数据集
     */
    private var navDataSource = ArrayList<FileNavBeanImpl>()
    /**
     * 文件夹为空时展示的空视图
     */
    private var selectedCount: AtomicInteger = AtomicInteger(0)
    private val maxSelectable = FilePickerManager.config?.maxSelectable ?: Int.MAX_VALUE
    private val isMultiple = FilePickerManager.config?.isMultiple ?: false
    private val isSkipDir = FilePickerManager.config?.isSkipDir ?: true

    val pickerConfig by lazy { FilePickerManager.config }
    private val fileListListener: RecyclerViewListener by lazy { getListener(rvContentList!!) }
    private val navListener: RecyclerViewListener by lazy { getListener(rvNav!!) }

//    private var operationView: ViewGroup? = null

    private var selectAllBtn: Button? = null
    private var confirmBtn: Button? = null
    private var rvContentList: RecyclerViewFilePicker? = null
    private var rvNav: RecyclerView? = null
    //    private var tvToolTitle: TextView? = null
    override fun onCreate(savedInstanceState: Bundle?) {
        setTheme(pickerConfig?.themeId ?: R.style.FilePickerThemeReply)
        super.onCreate(savedInstanceState)
        setContentView(R.layout.main_activity_for_file_picker)
        // 检查权限
        if (isPermissionGrated()) {
            prepareLauncher()
        } else {
            requestPermission()
        }
    }

    private fun isPermissionGrated(): Boolean {
        return ContextCompat.checkSelfPermission(
            this,
            Manifest.permission.READ_EXTERNAL_STORAGE
        ) == PackageManager.PERMISSION_GRANTED
    }

    /**
     * 申请权限
     */
    private fun requestPermission() {
        ActivityCompat.requestPermissions(
            this@FilePickerActivity,
            arrayOf(Manifest.permission.READ_EXTERNAL_STORAGE),
            FILE_PICKER_PERMISSION_REQUEST_CODE
        )
    }

    override fun onRequestPermissionsResult(
        requestCode: Int,
        permissions: Array<out String>,
        grantResults: IntArray
    ) {
        when (requestCode) {
            FILE_PICKER_PERMISSION_REQUEST_CODE -> {
                if (grantResults.isEmpty() || grantResults[0] != PackageManager.PERMISSION_GRANTED) {
                    Toast.makeText(
                        this@FilePickerActivity.applicationContext,
                        getString(string.file_picker_request_permission_failed),
                        Toast.LENGTH_SHORT
                    ).show()
                } else {
                    prepareLauncher()
                }
            }
        }
    }

    /**
     * 在做完权限申请之后开始的真正的工作
     */
    private fun prepareLauncher() {
        launch {
            if (Environment.getExternalStorageState() != MEDIA_MOUNTED) {
                throw Throwable(cause = IllegalStateException("External storage is not available ====>>> Environment.getExternalStorageState() != MEDIA_MOUNTED"))
            }
            initView()
            // 加载中布局
            initLoadingView()
            reloadList()
        }
    }

    private fun initView() {

        findViewById<ImageButton>(R.id.btn_go_back_file_picker).apply {
            setOnClickListener(this@FilePickerActivity)
        }

        // operationView
        findViewById<ViewGroup>(R.id.ll_operation_file_picker).apply {
            FilePickerManager.config?.isMultiple?.let {
                visibility = if (it) View.VISIBLE else View.GONE
            }
        }

        selectAllBtn = findViewById<Button>(R.id.btn_selected_all_file_picker).apply {
            setOnClickListener(this@FilePickerActivity)
            FilePickerManager.config?.selectAllText?.let {
                text = it
            }
        }

        confirmBtn = findViewById<Button>(R.id.btn_confirm_file_picker).apply {
            setOnClickListener(this@FilePickerActivity)
        }

        rvContentList = findViewById(R.id.rv_list_file_picker)
        rvNav = findViewById(R.id.rv_nav_file_picker)

    }

    private fun reloadList() {
        launch {
            val rootFile = if (navDataSource.isEmpty()) {
                FileUtils.suspendGetRootFile()
            } else {
                File(navDataSource.last().filePath)
            }
            val listData = FileUtils.suspendProduceListDataSource(rootFile, this@FilePickerActivity)
            // 导航栏数据集
            navDataSource = FileUtils.produceNavDataSource(
                navDataSource,
                if (navDataSource.isEmpty()) {
                    rootFile.path
                } else {
                    navDataSource.last().filePath
                },
                this@FilePickerActivity
            )
            initRv(listData, navDataSource)
            setLoadingFinish()
        }
    }

    private fun setLoadingFinish() {
        swipeRefreshLayout?.isRefreshing = false
    }

    private fun initLoadingView() {
        swipeRefreshLayout = findViewById(R.id.srl)
        swipeRefreshLayout?.apply {
            setOnRefreshListener {
                reloadList()
            }
            isRefreshing = true
            setColorSchemeColors(
                *resources.getIntArray(
                    when (pickerConfig?.themeId) {
                        R.style.FilePickerThemeCrane -> {
                            R.array.crane_swl_colors
                        }
                        R.style.FilePickerThemeReply -> {
                            R.array.reply_swl_colors
                        }
                        R.style.FilePickerThemeShrine -> {
                            R.array.shrine_swl_colors
                        }
                        else -> {
                            R.array.rail_swl_colors
                        }
                    }
                )
            )
        }
    }

    private fun initRv(
        listData: ArrayList<FileItemBeanImpl>?,
        navDataList: ArrayList<FileNavBeanImpl>
    ) {
        listData?.let { switchButton(true) }
        // 导航栏适配器
        rvNav?.apply {
            navAdapter = produceNavAdapter(navDataList)
            adapter = navAdapter
            layoutManager =
                LinearLayoutManager(this@FilePickerActivity, LinearLayoutManager.HORIZONTAL, false)
            removeOnItemTouchListener(navListener)
            addOnItemTouchListener(navListener)
        }

        // 列表适配器
        listAdapter = produceListAdapter(listData)
        rvContentList?.apply {
            emptyView = LayoutInflater.from(context)
                .inflate(R.layout.empty_file_list_file_picker, null, false)
            adapter = listAdapter
            layoutAnimation = AnimationUtils.loadLayoutAnimation(
                context,
                R.anim.layout_item_anim_file_picker
            )
            layoutManager = PosLinearLayoutManager(
                context,
                OrientationHelper.VERTICAL,
                false
            )
            addItemDecoration(
                LinerItemDecoration.Builder(context, OrientationHelper.VERTICAL)
                    .setHeadViewCount(0)
                    .setDividerColorProvider(object : BaseItemDecoration.DividerColorProvider {
                        override fun getDividerColor(position: Int, parent: RecyclerView): Int {
                            return Color.GRAY
                        }
                    })
                    .showLastDivider(true)
                    .setDividerWidthPx(1).build()
            )
            removeOnItemTouchListener(fileListListener)
            addOnItemTouchListener(fileListListener)
        }
        cleanStatus()
    }

    /**
     * 获取两个列表的监听器
     */
    private fun getListener(recyclerView: RecyclerView): RecyclerViewListener {
        return RecyclerViewListener(
            this@FilePickerActivity,
            recyclerView,
            this@FilePickerActivity
        )
    }

    /**
     * 构造列表的适配器
     */
    private fun produceListAdapter(dataSource: ArrayList<FileItemBeanImpl>?): FileListAdapter {
        return FileListAdapter(this@FilePickerActivity, dataSource)
    }

    /**
     * 构造导航栏适配器
     */
    private fun produceNavAdapter(dataSource: ArrayList<FileNavBeanImpl>): FileNavAdapter {
        return FileNavAdapter(this@FilePickerActivity, dataSource)
    }

    private val currPosMap: HashMap<String, Int> by lazy {
        HashMap<String, Int>(4)
    }

    private val currOffsetMap: HashMap<String, Int> by lazy {
        HashMap<String, Int>(4)
    }

    /**
     * 保存当前文件夹被点击项，下次进入时将滑动到此
     */
    private fun saveCurrPos(item: FileNavBeanImpl?, position: Int) {
        item?.run {
            currPosMap[filePath] = position
            (rvContentList?.layoutManager as? LinearLayoutManager)?.let {
                currOffsetMap.put(filePath, it.findViewByPosition(position)?.top ?: 0)
            }
        }
    }

    /**
     * 传递 item 点击事件给调用者
     */
    override fun onItemClick(
        recyclerAdapter: RecyclerView.Adapter<RecyclerView.ViewHolder>,
        view: View,
        position: Int
    ) {
        val item = (recyclerAdapter as BaseAdapter).getItem(position)
        item ?: return
        val file = File(item.filePath)
        if (!file.exists()) {
            Toast.makeText(
                this@FilePickerActivity.applicationContext,
                resources.getString(R.string.file_not_exist_tips),
                Toast.LENGTH_LONG
            ).show()
            return
        }
        when (view.id) {
            R.id.item_list_file_picker -> {
                if (file.isDirectory) {
                    (rvNav?.adapter as? FileNavAdapter)?.let {
                        saveCurrPos(it.data.last(), position)
                    }
                    // 如果是文件夹，则进入
                    enterDirAndUpdateUI(item)
                } else {
                    if (isMultiple) {
                        val f = item as FileItemBeanImpl
                        when {
                            f.isChecked() -> {
                                // 当前被选中，现在取消选中
                                selectedCount.decrementAndGet()
                                f.setCheck(false)
                                recyclerAdapter.notifyDataSetChanged()
                            }
                            isCanSelect() -> {
                                // 新增选中项情况
                                selectedCount.incrementAndGet()
                                f.setCheck(true)
                                recyclerAdapter.notifyDataSetChanged()
                            }
                            else -> {
                                // 新增失败的情况
                                Toast.makeText(
                                    this@FilePickerActivity.applicationContext,
                                    resources.getString(
                                        R.string.max_select_count_tips,
                                        maxSelectable
                                    ),
                                    Toast.LENGTH_SHORT
                                ).show()
                            }
                        }
                        FilePickerManager.config?.fileItemOnClickListener?.onItemClick(
                            recyclerAdapter,
                            view,
                            position
                        )
                    } else {
                        onSingleFinish(item.filePath)
                    }
                }
            }
            R.id.item_nav_file_picker -> {
                if (file.isDirectory) {
                    (rvNav?.adapter as? FileNavAdapter)?.let {
                        saveCurrPos(it.data.last(), position)
                    }
                    // 如果是文件夹，则进入
                    enterDirAndUpdateUI(item)
                }
            }
        }
    }

    /**
     * 长按
     */
    override fun onItemLongClick(
        recyclerAdapter: RecyclerView.Adapter<RecyclerView.ViewHolder>,
        view: View,
        position: Int
    ) {
        if (view.id != R.id.item_list_file_picker) return
        val item = (recyclerAdapter as FileListAdapter).getItem(position)
        item ?: return
        val file = File(item.filePath)
        if (!file.exists()) {
            Toast.makeText(
                this@FilePickerActivity.applicationContext,
                resources.getString(R.string.file_not_exist_tips),
                Toast.LENGTH_LONG
            ).show()
            return
        }

        // 如果是文件夹并且没有略过文件夹
        if (file.isDirectory && isSkipDir) return

        if (isMultiple) {
            when {
                item.isChecked() -> {
                    // 当前被选中，现在取消选中
                    selectedCount.decrementAndGet()
                    item.setCheck(false)
                    recyclerAdapter.notifyDataSetChanged()
                }
                isCanSelect() -> {
                    // 新增选中项情况
                    selectedCount.incrementAndGet()
                    item.setCheck(true)
                    recyclerAdapter.notifyDataSetChanged()
                }
                else -> {
                    // 新增失败的情况
                    Toast.makeText(
                        this@FilePickerActivity.applicationContext,
                        resources.getString(R.string.max_select_count_tips, maxSelectable),
                        Toast.LENGTH_SHORT
                    ).show()
                }
            }
        } else {
            onSingleFinish(item.filePath)
        }
    }

    /**
     * 子控件被点击
     */
    override fun onItemChildClick(
        recyclerAdapter: RecyclerView.Adapter<RecyclerView.ViewHolder>,
        view: View,
        position: Int
    ) {
        when (view.id) {
            R.id.tv_btn_nav_file_picker -> {
                val item = (recyclerAdapter as FileNavAdapter).getItem(position)
                item ?: return
                enterDirAndUpdateUI(item)
            }
            else -> {
                val item = (recyclerAdapter as FileListAdapter).getItem(position)
                item ?: return
                // 文件夹直接进入
                if (item.isDir && isSkipDir) {
                    enterDirAndUpdateUI(item)
                    return
                }
                when {
                    item.isChecked() -> {
                        // 当前被选中，现在取消选中
                        selectedCount.decrementAndGet()
                        item.setCheck(false)
                        recyclerAdapter.notifyDataSetChanged()
                    }
                    isCanSelect() -> {
                        // 新增选中项情况
                        selectedCount.incrementAndGet()
                        item.setCheck(true)
                        recyclerAdapter.notifyDataSetChanged()
                    }
                    else -> {
                        // 新增失败的情况
                        Toast.makeText(
                            this@FilePickerActivity.applicationContext,
                            resources.getString(R.string.max_select_count_tips, maxSelectable),
                            Toast.LENGTH_SHORT
                        ).show()
                    }
                }
            }
        }
    }

    /**
     * 从导航栏中调用本方法，需要传入 pos，以便生产新的 nav adapter
     */
    private fun enterDirAndUpdateUI(fileBean: FileBean) {
        launch {
            //清除当前选中状态
            cleanStatus()

            // 获取文件夹文件
            val nextFiles = File(fileBean.filePath)

            // 更新列表数据集
            listAdapter?.data =
                FileUtils.suspendProduceListDataSource(nextFiles, this@FilePickerActivity)

            // 更新导航栏的数据集
            navDataSource = FileUtils.produceNavDataSource(
                ArrayList(navAdapter!!.data),
                fileBean.filePath,
                this@FilePickerActivity
            )
            navAdapter?.data = navDataSource

            navAdapter!!.notifyDataSetChanged()
            notifyDataChangedForList(fileBean)

            rvNav?.adapter?.itemCount?.let {
                rvNav?.smoothScrollToPosition(
                    if (it == 0) {
                        0
                    } else {
                        it - 1
                    }
                )
            }
        }
    }

    private fun notifyDataChangedForList(fileBean: FileBean) {
        rvContentList?.apply {
            (layoutManager as? PosLinearLayoutManager)?.setTargetPos(
                currPosMap[fileBean.filePath] ?: 0,
                currOffsetMap[fileBean.filePath] ?: 0
            )
            layoutAnimation = AnimationUtils.loadLayoutAnimation(
                context,
                R.anim.layout_item_anim_file_picker
            )
            adapter?.notifyDataSetChanged()
            scheduleLayoutAnimation()
        }
    }

    private fun switchButton(isEnable: Boolean) {
        confirmBtn?.isEnabled = isEnable
        selectAllBtn?.isEnabled = isEnable
    }

    private fun cleanStatus() {
        selectedCount.set(0)
        updateItemUI(false)
    }

    override fun updateItemUI(isCheck: Boolean) {
        // 取消选中，并且选中数为 0
        when {
            selectedCount.get() == 0 -> {
                confirmBtn!!.text = getString(string.file_picker_tv_select_done)
                selectAllBtn!!.text = getString(string.file_picker_tv_select_all)
            }
            selectedCount.get() >= maxSelectable -> {
                confirmBtn!!.text =
                    getString(string.file_picker_tv_select_done_format, selectedCount.get())
                selectAllBtn!!.text = getString(string.file_picker_tv_deselect_all)
            }
            selectedCount.get() >= listAdapter!!.itemCount -> {
                confirmBtn!!.text =
                    getString(string.file_picker_tv_select_done_format, selectedCount.get())
                selectAllBtn!!.text = getString(string.file_picker_tv_deselect_all)
            }
            else -> confirmBtn!!.text =
                getString(string.file_picker_tv_select_done_format, selectedCount.get())
        }
    }

    override fun onBackPressed() {
        if ((rvNav?.adapter as? FileNavAdapter)?.itemCount ?: 0 <= 1) {
            super.onBackPressed()
        } else {
            // 即将进入的 item 的索引
            (rvNav?.adapter as? FileNavAdapter)?.run {
                enterDirAndUpdateUI(getItem(this.itemCount - 2)!!)
            }
        }
    }

    override fun onClick(v: View?) {
        when (v!!.id) {
            // 全选
            R.id.btn_selected_all_file_picker -> {
                // 只要当前选中项数量大于 0，那么本按钮则为取消全选按钮
                if ((v as Button).text == getString(R.string.file_picker_tv_deselect_all)) {
                    for (data in listAdapter!!.data!!) {
                        data.setCheck(false)
                    }
                    selectedCount.set(0)
                } else if (isCanSelect()) {
                    // 当前选中数少于最大选中数，则即将执行选中
                    for (data in listAdapter!!.data!!) {
                        if(data.isChecked()){
                            continue
                        }
                        if (data.isDir && isSkipDir) {
                            continue
                        }
                        selectedCount.incrementAndGet()
                        data.setCheck(true)
                        if (selectedCount.get() >= maxSelectable) {
                            break
                        }
                    }
                }
                listAdapter!!.notifyDataSetChanged()
            }
            // 确认按钮
            R.id.btn_confirm_file_picker -> {
                val list = ArrayList<String>()
                val intent = Intent()

                for (data in listAdapter!!.data!!) {
                    if (data.isChecked()) {
                        list.add(data.filePath)
                    }
                }

                if (list.isEmpty()) {
                    this@FilePickerActivity.setResult(Activity.RESULT_CANCELED, intent)
                    finish()
                }

                FilePickerManager.saveData(list)
                this@FilePickerActivity.setResult(Activity.RESULT_OK, intent)
                finish()
            }

            R.id.btn_go_back_file_picker -> {
                finish()
            }
        }
    }

    /**
     * TODO 使用挂起函数解决遍历操作带来的阻塞问题 ，同一文件夹要缓存结果
     */
    private fun getAvailableCount(): Long {
        var count: Long = 0
        for (item in listAdapter!!.data!!) {
            val file = File(item.filePath)
            if (isSkipDir && file.exists() && file.isDirectory) {
                continue
            }
            count++
        }
        return count
    }

    /**
     * 是否可选择
     */
    private fun isCanSelect(): Boolean {
        var checkedCount = 0
        for (item in listAdapter!!.data!!) {
            if (item.isChecked()) checkedCount++
        }
        return (checkedCount < maxSelectable)
    }

    companion object {
        private const val FILE_PICKER_PERMISSION_REQUEST_CODE = 10201
    }

    private fun onSingleFinish(filePath: String) {
        val list = ArrayList<String>()
        list.add(filePath)
        FilePickerManager.saveData(list)
        this@FilePickerActivity.setResult(Activity.RESULT_OK, Intent())
        finish()
    }

}
